/**
 * @Author: zhongyang
 * @Date: 2022/6/25 12:58
 */

package main

import "fmt"

/**
05_原型模式
概念：这种模式是实现了一个原型接口，该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时，则采用这种模式。
总的来说就是不直接new新对象，而是直接复制出来。
*/

// 1.原型对象需要实现的接口
type Cloneable interface {
	Clone() Cloneable
}

// 2.原型对象的类
type PrototypeManager struct {
	prototypes map[string]Cloneable
}

// 3.原型对象操作
func NewPrototypeManager() *PrototypeManager {
	return &PrototypeManager{prototypes: make(map[string]Cloneable)}
}

func (p *PrototypeManager) Set(name string, prototype Cloneable) {
	p.prototypes[name] = prototype
}

func (p *PrototypeManager) Get(name string) Cloneable {
	return p.prototypes[name]
}

type Type1 struct {
	name string
}

func (t *Type1) Clone() Cloneable {
	t1 := *t
	return &t1
}

type Type2 struct {
	age int64
}

func (t *Type2) Clone() Cloneable {
	return t
}

func main() {
	manager := NewPrototypeManager()
	manager.Set("jz", &Type1{name: "江洲"})
	clone1 := manager.Get("jz")
	clone2 := clone1.Clone()
	// 比较地址值
	if clone1 == clone2 {
		fmt.Println("浅拷贝")
	} else {
		fmt.Println("深拷贝")
	}

	manager.Set("ok", &Type2{age: 23})
	c1 := manager.Get("ok")
	c2 := c1.Clone()
	if c1 == c2 {
		fmt.Println("浅拷贝")
	} else {
		fmt.Println("深拷贝")
	}
}
